home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 24
/
Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso
/
Aminet
/
dev
/
c
/
AmiVoGL_MDEV.lha
/
src
/
polygons.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-04-12
|
24KB
|
1,278 lines
#include <stdio.h>
#include "vogl.h"
/* --------------------------------------------------------------------- */
#ifdef AZTEC_C
#include <math.h>
#else
extern double cos();
extern double sin();
#endif
/* ---------------------------------------------------------------------
* Definitions:
*/
#define MAX(x, y) ((x) > (y) ? (x) : (y))
#define MIN(x, y) ((x) < (y) ? (x) : (y))
#define ABS(x) ((x) < 0 ? -(x) : (x))
/* ---------------------------------------------------------------------
* Local Variables:
*/
static float F[6][4], S[6][4], I[4], p[MAXVERTS][4];
static int nout, first[6], numv;
static long polymodeflag = PYM_FILL;
static int ip1[MAXVERTS], ip2[MAXVERTS];
/*
* Orientation of backfacing polygons(in screen coords)
*/
static int clockwise = 1;
/* ---------------------------------------------------------------------
* Prototypes:
*/
#ifdef __PROTOTYPE__
static void dopoly(int); /* polygons.c */
static void polyoutline( int, int[], int[]); /* polygons.c */
static int checkbacki(void); /* polygons.c */
static void polyclip(register int); /* polygons.c */
static void shclip( float[4], int); /* polygons.c */
static void shclose(int); /* polygons.c */
static intersect( int, register Vector, /* polygons.c */
register Vector);
static visible(int); /* polygons.c */
#else /* __PROTOTYPE__ */
static void dopoly(); /* polygons.c */
static void polyoutline(); /* polygons.c */
static int checkbacki(); /* polygons.c */
static void polyclip(); /* polygons.c */
static void shclip(); /* polygons.c */
static void shclose(); /* polygons.c */
static intersect(); /* polygons.c */
static visible(); /* polygons.c */
#endif /* __PROTOTYPE__ */
/*
* concave
*
* signal wether or not polygons are concave (not a lot of use at the moment).
*/
void concave(Boolean yesno)
{
vdevice.concave = yesno;
}
/* ------------------------------------------------------------------------ */
/*
* backface
*
* Turns on culling of backfacing polygons. A polygon is
* backfacing if it's orientation in *screen* coords is clockwise.
*/
void backface(int onoff)
{
vdevice.attr->a.backface = onoff;
clockwise = 1;
}
/* ------------------------------------------------------------------------ */
/*
* frontface
*
* Turns on culling of frontfacing polygons. A polygon is
* frontfacing if it's orientation in *screen* coords is anti-clockwise.
*/
void frontface(int onoff)
{
vdevice.attr->a.backface = onoff;
clockwise = 0;
}
/* ------------------------------------------------------------------------ */
/*
* polymode
*
* Sets the polygon filling mode - only filled or outlined supported
*/
void polymode(long mode)
{
/*
* On older SGI Machines this call used to work... On the newer
* boxes it doesn't do anything. If you want the old stuff then
* #define OLD_SGI_BOXES somewhere.
*/
#ifdef OLD_SGI_BOXES
polymodeflag = mode;
#endif
}
/* ------------------------------------------------------------------------ */
/*
* dopoly
*
* do a transformed polygon with n edges using fill
*/
static void dopoly(int n)
{
int i;
char buf[100];
if (n > MAXVERTS) {
sprintf(buf, "dopoly: can't fill a polygon with more than %d vertices", MAXVERTS);
verror(buf);
}
if (!vdevice.clipoff) {
polyclip(n);
}
else {
nout = n;
for (i = 0; i < n; i++) {
ip1[i] = WtoVx(p[i]);
ip2[i] = WtoVy(p[i]);
}
}
if (vdevice.attr->a.backface && checkbacki()) {
vdevice.fill = 0;
return;
}
if (vdevice.fill) {
if (nout > 2) {
(*vdevice.dev.Vfill)(nout, ip1, ip2);
}
}
else {
vdevice.cpVx = ip1[0];
vdevice.cpVy = ip2[0];
vdevice.cpVvalid = 0;
polyoutline(nout, ip1, ip2);
}
vdevice.fill = 0;
}
/* ------------------------------------------------------------------------ */
/*
* polyoutline
*
* draws a polygon outline from already transformed points.
*/
static void polyoutline(
int n,
int ipx[],
int ipy[])
{
int i;
if (n > 2) {
for (i = 1; i < n; i++) {
(*vdevice.dev.Vdraw)(ipx[i], ipy[i]);
vdevice.cpVx = ipx[i];
vdevice.cpVy = ipy[i];
}
(*vdevice.dev.Vdraw)(ipx[0], ipy[0]);
vdevice.cpVx = ipx[0];
vdevice.cpVy = ipy[0];
}
}
/* ------------------------------------------------------------------------ */
/*
* polyobj
*
* construct a polygon from a object token list.
*/
void polyobj(
int n,
Token dp[],
int fill)
{
int i, j;
float vect[4], result[4];
for (i = 0, j = 0; i < n; i++, j += 3) {
vect[V_X] = dp[j + V_X].f;
vect[V_Y] = dp[j + V_Y].f;
vect[V_Z] = dp[j + V_Z].f;
vect[V_W] = 1;
multvector(result, vect, vdevice.transmat->m);
p[i][V_X] = result[V_X];
p[i][V_Y] = result[V_Y];
p[i][V_Z] = result[V_Z];
p[i][V_W] = result[V_W];
}
if (fill)
vdevice.fill = polymodeflag;
else
vdevice.fill = 0;
dopoly(n);
vdevice.cpW[V_X] = dp[V_X].f;
vdevice.cpW[V_Y] = dp[V_Y].f;
vdevice.cpW[V_Z] = dp[V_Z].f;
}
/* ------------------------------------------------------------------------ */
/*
* poly2
*
* construct a polygon from an (x, y) array of points provided by the user.
*/
void poly2(
long nv,
float dp[][2])
{
int i;
float np[MAXVERTS][3];
if (!vdevice.initialised)
verror("poly2: vogl not initialised");
vdevice.fill = 0;
for (i = 0; i < (int)nv; i++) {
np[i][V_X] = dp[i][V_X];
np[i][V_Y] = dp[i][V_Y];
np[i][V_Z] = 0.0;
}
poly(nv, np);
}
/* ------------------------------------------------------------------------ */
/*
* poly2i
*
* construct a polygon from an (x, y) array of points provided by the user.
* Icoord version.
*/
void poly2i(
long nv,
Icoord dp[][2])
{
int i;
float np[MAXVERTS][3];
if (!vdevice.initialised)
verror("poly2i: vogl not initialised");
vdevice.fill = 0;
for (i = 0; i < (int)nv; i++) {
np[i][V_X] = dp[i][V_X];
np[i][V_Y] = dp[i][V_Y];
np[i][V_Z] = 0.0;
}
poly(nv, np);
}
/* ------------------------------------------------------------------------ */
/*
* poly2s
*
* construct a polygon from an (x, y) array of points provided by the user.
* Scoord version.
*/
void poly2s(
long nv,
Scoord dp[][2])
{
int i;
float np[MAXVERTS][3];
if (!vdevice.initialised)
verror("poly2s: vogl not initialised");
vdevice.fill = 0;
for (i = 0; i < (int)nv; i++) {
np[i][V_X] = dp[i][V_X];
np[i][V_Y] = dp[i][V_Y];
np[i][V_Z] = 0.0;
}
poly(nv, np);
}
/* ------------------------------------------------------------------------ */
/*
* polyi
*
* construct a polygon from an (x, y, z) array of points provided by the user.
* Icoord version.
*/
void polyi(
long nv,
Icoord dp[][3])
{
int i;
float np[MAXVERTS][3];
if (!vdevice.initialised)
verror("polyi: vogl not initialised");
vdevice.fill = 0;
for (i = 0; i < (int)nv; i++) {
np[i][V_X] = dp[i][V_X];
np[i][V_Y] = dp[i][V_Y];
np[i][V_Z] = dp[i][V_Z];
}
poly(nv, np);
}
/* ------------------------------------------------------------------------ */
/*
* polys
*
* construct a polygon from an (x, y, z) array of points provided by the user.
* Scoord version.
*/
void polys(
long nv,
Scoord dp[][3])
{
int i;
float np[MAXVERTS][3];
if (!vdevice.initialised)
verror("poly2s: vogl not initialised");
vdevice.fill = 0;
for (i = 0; i < (int)nv; i++) {
np[i][V_X] = dp[i][V_X];
np[i][V_Y] = dp[i][V_Y];
np[i][V_Z] = dp[i][V_Z];
}
poly(nv, np);
}
/* ------------------------------------------------------------------------ */
/*
* polf2
*
* construct a filled polygon from an (x, y) array of points provided
* by the user.
*/
void polf2(
long nv,
float dp[][2])
{
int i;
float np[MAXVERTS][3];
if (!vdevice.initialised)
verror("polf2: vogl not initialised");
vdevice.fill = polymodeflag;
for (i = 0; i < (int)nv; i++) {
np[i][V_X] = dp[i][V_X];
np[i][V_Y] = dp[i][V_Y];
np[i][V_Z] = 0.0;
}
poly(n